package com.ruoyi.controller;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.redis.util.RedisUtils;
import com.ruoyi.common.utils.*;
import com.ruoyi.service.IAccessTokenService;
import com.ruoyi.service.ISysLoginService;
import com.ruoyi.system.auth.annotation.HasPermissions;
import com.ruoyi.system.domain.User;
import com.ruoyi.system.domain.UserOnline;
import com.ruoyi.system.log.annotation.OperLog;
import com.ruoyi.system.log.enums.BusinessType;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;

/**
 * 在线用户记录 提供者
 *
 * @author ruoyi
 * @date 2020-09-24
 */
@RestController
@RequestMapping("monitor/online")
public class OnlineController extends BaseController {

    @Autowired
    private IAccessTokenService tokenService;

    @Autowired
    private ISysLoginService sysLoginService;

    @Autowired
    private RedisUtils redisUtils;


    /**
     * 查询在线用户记录列表
     */
    @HasPermissions("monitor:online:list")
    @GetMapping("list")
    public TableDataInfo list(String ipaddr, String loginName) {
        Set<String> onlineKeys = redisUtils.keys(Constants.ACCESS_TOKEN + "*");
        List<UserOnline> userOnlineList = Lists.newArrayList();
        for (String onlineKey : onlineKeys) {
            HttpServletRequest request = ServletUtils.getRequest();
            final UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
            final String ip = IpUtils.getIpAddr(request);
            // 获取客户端操作系统
            String os = userAgent.getOperatingSystem().getName();
            // 获取客户端浏览器
            String browser = userAgent.getBrowser().getName();
            // 获取用户
            User user = redisUtils.get(onlineKey, User.class);
            UserOnline userOnline = new UserOnline();
            userOnline.setTokenId(StringUtils.replace(onlineKey, Constants.ACCESS_TOKEN, ""));
            userOnline.setLoginName(user.getLoginName());
            userOnline.setDeptName(user.getDept().getDeptName());
            userOnline.setIpaddr(ip);
            userOnline.setLoginTime(DateUtils.getNowDate());
            userOnline.setBrowser(browser);
            userOnline.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
            userOnline.setOs(os);

            // 添加用户
            if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(loginName)) {
                if (StringUtils.equals(ipaddr, user.getLoginIp()) && StringUtils.equals(loginName, user.getLoginName())) {
                    userOnlineList.add(userOnline);
                }
            }
            if (StringUtils.isNotEmpty(ipaddr)) {
                if (StringUtils.equals(ipaddr, user.getLoginIp())) {
                    userOnlineList.add(userOnline);
                }
            }
            if (StringUtils.isNotEmpty(loginName)) {
                if (StringUtils.equals(loginName, user.getLoginName())) {
                    userOnlineList.add(userOnline);
                }
            }
            if (StringUtils.isEmpty(ipaddr) && StringUtils.isEmpty(loginName)) {
                userOnlineList.add(userOnline);
            }
        }
        return getDataTable(userOnlineList);
    }

    /**
     * 强退用户
     */
    @HasPermissions("monitor:online:forceLogout")
    @OperLog(title = "在线用户", businessType = BusinessType.FORCE)
    @PostMapping("forceLogout")
    public R forceLogout(String tokenId) {
        User user = tokenService.queryByToken(tokenId);
        if (null != user) {
            sysLoginService.logout(user.getLoginName());
            tokenService.expireToken(user.getUserId());
        }
        return R.ok();
    }

}
